<?php

require_once(dirname(__FILE__) . '/../lib/httpsqs.php');

$threads = new threadManager();
$threads->exec();

/**
 * PHP 进程管理器
 * 
 * @author hzjsq@msn.com
 * @version 0.1b
 */
class threadManager {

    /**
     * PHP执行文件名
     * @var String
     */
    private $executable = "/usr/local/php/bin/php";
    /**
     * 脚本所在目录
     * @var String
     */
    private $script = "/data/httpd/dev.fh.taoex.com/script/thread/initFhOrder.php";
    /**
     * 所有执行的所有 HOSTS列表
     * @var Array
     */
    private $params = array();
    /**
     * 当前运行的线程数
     * @var Integer
     */
    private $threadRunning = 0;
    /**
     * 同时运行线程数
     * @var Integer
     */
    private $maxThread = 8;
    /**
     * 运行中的线程对象
     * var Array
     */
    private $running = array();
    /**
     * 等待时间
     * @var Integer
     */
    private $waitTime = 10000;

    /**
     * 开始执行任务
     * 
     * @param void
     * @return void
     */
    public function exec() {

        for (;;) {
            
            $httpsqs = new httpsqs();
            $status = json_decode($httpsqs->status_json('192.168.10.105', '1218', 'utf-8', 'fh-init'), true);

            //执行死循环
            while (($this->threadRunning < $this->maxThread) && ($status['unread'] > 0)) {
                
                $domain = $httpsqs->get('192.168.10.105', '1218', 'utf-8', 'fh-init');
                echo sprintf("Init %s Orders\n", $domain);
                $this->running[] = & new thread($this->executable, $this->script, $domain . ' ' .
                                (time()-86400*3) . ' ' . time(), 10);
                $this->threadRunning++;
                $status = json_decode($httpsqs->status_json('192.168.10.105', '1218', 'utf-8', 'fh-init'), true);
            }

            //检查是否已经结束 
//            if (($this->threadRunning == 0) && ($status['unread'] == 0)) {
//
//                break;
//            }

            //等待代码执行完成
            $this->sleep($this->waitTime);

            //检查已经完成的任务
            foreach ($this->running as $idx => $thread) {

                if (!$thread->isRunning() || $thread->isOverExecuted()) {

                    if (!$thread->isRunning())
                        echo sprintf("Done: %s\n", $thread->param);
                    else
                        echo sprintf("Kill: %s\n", $thread->param);

                    proc_close($thread->resource);
                    unset($this->running[$idx]);
                    $this->threadRunning--;
                }
            }
        }
    }

    /**
     * 等待，空循环
     * 
     * @param integer $times 循环次数
     * @return void 
     */
    private function sleep($times) {

        //for ($i=0; $i<$times; $i++);
        usleep($times);
    }

}

class thread {

    /**
     * 句柄
     * @var resource
     */
    public $resource;
    /**
     * 管道
     * @var resource
     */
    public $pipes;
    /**
     * 执行参数
     * @var String
     */
    public $param;
    /**
     * 超时时长
     * @var Integer
     */
    private $maxExecTime;
    /**
     * 脚本开始执行时间
     * @var Integer
     */
    private $startTime;

    /**
     * 析构
     * 
     * @param string $executable PHP执行文件名
     * @param string $script PHP脚本名
     * @param string $param 脚本执行参数
     * @param integer $maxExecTime 超时间设置
     * @return void
     */
    function __construct(&$executable, &$script, $param, $maxExecTime) {

        $this->param = $param;
        $this->maxExecTime = $maxExecTime;
        $descriptorspec = array(
            0 => array('pipe', 'r'),
            1 => array('pipe', 'w'),
            2 => array('pipe', 'w')
        );

        $this->resource = proc_open($executable . " " . $script . " " . $this->param, $descriptorspec, $this->pipes, null, $_ENV);
        $this->startTime = time();
    }

    /**
     * 检查任务是否运行中
     * 
     * @param void
     * @return boolean
     */
    function isRunning() {

        $status = proc_get_status($this->resource);
        return $status["running"];
    }

    /**
     * 检查运行是否超时
     * 
     * @param void
     * @return boolean
     */
    function isOverExecuted() {
        
        return false;
//        if (($this->startTime + $this->maxExecTime) < time())
//            return true;
//        else
//            return false;
    }

}